package com.yy.auth.server.service;

import org.springframework.context.annotation.Bean;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.security.oauth2.core.oidc.OidcScopes;
import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
import org.springframework.security.oauth2.server.authorization.settings.ClientSettings;
import org.springframework.security.oauth2.server.authorization.settings.TokenSettings;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Description 使用客户端注册服务
 * @Date 2025/10/11 下午2:45
 * @Author yanglin
 **/
@Service
public class ClientRegistrationService {

    private final PasswordEncoder passwordEncoder;
    private final Map<String, RegisteredClient> clients = new ConcurrentHashMap<>();

    public ClientRegistrationService(PasswordEncoder passwordEncoder) {
        this.passwordEncoder = passwordEncoder;
        registerDefaultClients();
    }

    private void registerDefaultClients() {
        registerClient("client1", "http://localhost:8081/login/oauth2/code/client1");
        registerClient("client2", "http://localhost:8082/login/oauth2/code/client2");
    }

    public void registerClient(String clientId, String redirectUri) {
        if (clients.containsKey(clientId)) {
            throw new IllegalArgumentException("Client ID already registered: " + clientId);
        }

        String rawSecret = "secret";
        String encodedSecret = passwordEncoder.encode(rawSecret);

        RegisteredClient client = RegisteredClient.withId(UUID.randomUUID().toString())
                .clientId(clientId)
                .clientSecret(encodedSecret)
                .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
                .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
                .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
                .redirectUri(redirectUri)
                .scope(OidcScopes.OPENID)
                .scope("read")
                .tokenSettings(tokenSettings())
                .clientSettings(ClientSettings.builder().requireAuthorizationConsent(false).build())
                .build();

        clients.put(clientId, client);
    }

    public RegisteredClientRepository registeredClientRepository() {
        return new InMemoryRegisteredClientRepository(clients.values().stream().toList());
    }

    public TokenSettings tokenSettings() {
        return TokenSettings.builder()
                // 设置授权码有效期为 10 分钟
                .authorizationCodeTimeToLive(Duration.ofMinutes(10))
                // 设置访问令牌有效期
                .accessTokenTimeToLive(Duration.ofHours(1))
                // 设置刷新令牌有效期
                .refreshTokenTimeToLive(Duration.ofDays(30))
                .build();
    }
}
